package cn.highset.modules.base.controller.manage;

import cn.highset.common.utils.JPinYinUtil;
import cn.highset.common.utils.PageUtil;
import cn.highset.common.utils.ResultUtil;
import cn.highset.common.vo.PageVo;
import cn.highset.common.vo.Result;
import cn.highset.common.vo.SearchVo;
import cn.highset.modules.base.dao.mapper.ProductTypeMapper;
import cn.highset.modules.base.entity.Exhibitor;
import cn.highset.modules.base.entity.ExhibitorProductType;
import cn.highset.modules.base.entity.ProductType;
import cn.highset.modules.base.factory.ExhibitorFactory;
import cn.highset.modules.base.service.ExhibitorProductTypeService;
import cn.highset.modules.base.service.ExhibitorService;
import cn.highset.modules.base.service.ProductTypeService;
import cn.highset.modules.base.service.mybatis.IProductTypeService;
import cn.highset.modules.base.vo.ExcelImportResult;
import cn.highset.modules.base.vo.ExhibitorImport;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.util.*;

/**
 * @author Victor
 */
@Slf4j
@RestController
@Api(description = "展商管理接口")
@RequestMapping("/highset/exhibitor")
@Transactional
public class ExhibitorController {

    @Autowired
    private ExhibitorService exhibitorService;
    @Autowired
    private ExhibitorProductTypeService exhibitorProductTypeService;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private IProductTypeService iProductTypeService;
    @PersistenceContext
    private EntityManager entityManager;
    @Autowired
    private ProductTypeMapper productTypeMapper;
    @Autowired
    private ProductTypeService productTypeService;

    @PostMapping(value = "/getByCondition")
    @ApiOperation(value = "多条件分页获取")
    public Result<Page<Exhibitor>> getByCondition(@ModelAttribute Exhibitor exhibitor,
                                                  @ModelAttribute SearchVo searchVo,
                                                  @ModelAttribute PageVo pageVo) {

        Page<Exhibitor> page = exhibitorService.findByCondition(exhibitor, searchVo, PageUtil.initPage(pageVo));
        page.getContent().forEach(e -> {
            List<ProductType> pts = iProductTypeService.findByExhibitorId(e.getId(),null);
            if (CollUtil.isNotEmpty(pts)) {
                String[] ids = new String[pts.size()];
                String[] names = new String[pts.size()];
                for (int i = 0, lenI = pts.size(); i < lenI; i++) {
                    ProductType pt = pts.get(i);
                    ids[i] = pt.getId();
                    names[i] = pt.getNameCn();
                }
                e.setProductTypeIds(ids);
                e.setProductTypeNames(names);

            }
            entityManager.clear();
        });
        return new ResultUtil<Page<Exhibitor>>().setData(page);
    }

    @RequestMapping(value = "/add", method = RequestMethod.POST)
    @ApiOperation(value = "添加展商")
    public Result<Object> add(@ModelAttribute Exhibitor o) {
        if (StrUtil.hasBlank(o.getCompanyName(), o.getCompanyNameEn(), o.getStandNo())) {
            return new ResultUtil<Object>().setErrorMsg("缺少必需表单字段");
        }
        String companyNamePy = StrUtil.trimToEmpty(JPinYinUtil.changeToTonePinYin(o.getCompanyName()));
        o.setCompanyNamePy(companyNamePy.substring(0,Math.min(150,companyNamePy.length())));

        String companyNameEnPy = StrUtil.trimToEmpty(JPinYinUtil.changeToTonePinYin(o.getCompanyNameEn()));
        o.setCompanyNameEnPy(companyNameEnPy.substring(0,Math.min(150,companyNameEnPy.length())));
        Exhibitor bean = exhibitorService.save(o);
        if (bean == null) {
            return new ResultUtil<Object>().setErrorMsg("添加失败");
        }
        //删除原关联信息
        exhibitorProductTypeService.deleteByExhibitorId(bean.getId());
        String[] productTypeIds = o.getProductTypeIds();
        //存储产品类别
        if (ArrayUtil.isNotEmpty(productTypeIds)) {

            Set<String> typeIds= new HashSet<>();
            List<ProductType> types = productTypeService.findAllById(Arrays.asList(productTypeIds));
            if(CollUtil.isNotEmpty(types)){//通过子类  将其所有父级类别 归类
                for (ProductType type: types
                ) {
                    typeIds.add(type.getId());
                    String parentIds = type.getParentIds();
                    if(StrUtil.isNotBlank(parentIds)){
                        parentIds = parentIds.replaceAll("\\[","").replaceAll("]","");
                        String[] strs = parentIds.split(",");
                        if(ArrayUtil.isNotEmpty(strs)){
                            for (String str:strs
                            ) {
                                if(StrUtil.isNotBlank(str) && !"0".equals(str)){
                                    typeIds.add(str);
                                }

                            }
                        }
                    }

                }
            }

            if (CollUtil.isNotEmpty(typeIds)) {
                List<ExhibitorProductType> exhibitorProductTypeList = new ArrayList<>();
                for (String typeId : typeIds
                ) {
                    ExhibitorProductType ept = new ExhibitorProductType();
                    ept.setExhibitorId(bean.getId());
                    ept.setProductTypeId(typeId);
                    exhibitorProductTypeList.add(ept);
                }
                exhibitorProductTypeService.saveOrUpdateAll(exhibitorProductTypeList);
            }

        }
        //手动批量删除缓存 删除展商产品信息缓存
        Set<String> keys = redisTemplate.keys("productType::exhibitor:"+bean.getId() + "*");
        redisTemplate.delete(keys);
        return new ResultUtil<Object>().setSuccessMsg("添加成功");
    }

    @RequestMapping(value = "/edit", method = RequestMethod.POST)
    @ApiOperation(value = "修改展商", notes = "需要通过id获取原展商")
    public Result<Object> edit(@ModelAttribute Exhibitor o) {
        if (StrUtil.hasBlank(o.getId(), o.getCompanyName(), o.getCompanyNameEn(), o.getStandNo())) {
            return new ResultUtil<Object>().setErrorMsg("缺少必需表单字段");
        }

        Exhibitor old = exhibitorService.get(o.getId());

        Exhibitor bean = exhibitorService.update(ExhibitorFactory.edit(o, old));

        if (bean == null) {
            return new ResultUtil<Object>().setErrorMsg("修改失败");
        }
        //删除原关联信息
        exhibitorProductTypeService.deleteByExhibitorId(bean.getId());
        String[] productTypeIds = o.getProductTypeIds();
        //存储产品类别
        if (ArrayUtil.isNotEmpty(productTypeIds)) {

            Set<String> typeIds= new HashSet<>();
            List<ProductType> types = productTypeService.findAllById(Arrays.asList(productTypeIds));
            if(CollUtil.isNotEmpty(types)){//通过子类  将其所有父级类别 归类
                for (ProductType type: types
                ) {
                    typeIds.add(type.getId());
                    String parentIds = type.getParentIds();
                    if(StrUtil.isNotBlank(parentIds)){
                        parentIds = parentIds.replaceAll("\\[","").replaceAll("]","");
                        String[] strs = parentIds.split(",");
                        if(ArrayUtil.isNotEmpty(strs)){
                            for (String str:strs
                            ) {
                                if(StrUtil.isNotBlank(str) && !"0".equals(str)){
                                    typeIds.add(str);
                                }

                            }
                        }
                    }

                }
            }

            if (CollUtil.isNotEmpty(typeIds)) {
                List<ExhibitorProductType> exhibitorProductTypeList = new ArrayList<>();
                for (String typeId : typeIds
                ) {
                    ExhibitorProductType ept = new ExhibitorProductType();
                    ept.setExhibitorId(bean.getId());
                    ept.setProductTypeId(typeId);
                    exhibitorProductTypeList.add(ept);
                }
                exhibitorProductTypeService.saveOrUpdateAll(exhibitorProductTypeList);
            }

        }
        //手动批量删除缓存 删除展商产品信息缓存
        Set<String> keys = redisTemplate.keys("productType::exhibitor:"+bean.getId() + "*");
        redisTemplate.delete(keys);
        return new ResultUtil<Object>().setSuccessMsg("修改成功");
    }

    @RequestMapping(value = "/delByIds/{ids}", method = RequestMethod.DELETE)
    @ApiOperation(value = "批量通过ids删除", notes = "逻辑删除")
    @ApiImplicitParams(value = {
            @ApiImplicitParam(paramType = "path", name = "ids", value = "展商ID数组", dataType = "String", required = true, allowMultiple = true),
    })
    public Result<Object> delAllByIds(@PathVariable String[] ids) {

        for (String id : ids) {
            exhibitorService.delete(id);
            //删除原关联信息
            exhibitorProductTypeService.deleteByExhibitorId(id);
        }
        //手动批量删除缓存 删除展商产品信息缓存
        Set<String> keys = redisTemplate.keys("productType::exhibitor:"+ "*");
        redisTemplate.delete(keys);
        return new ResultUtil<Object>().setSuccessMsg("批量通过id删除数据成功");
    }


    @RequestMapping(value = "/import", method = RequestMethod.POST)
    @ApiOperation(value = "导入展商数据")
    public Result<Object> importMethod(@RequestBody List<ExhibitorImport> dataList) {

        List<Integer> errors = new ArrayList<>();
        List<ExcelImportResult.Error> errorList = new ArrayList<>();
        int count = 0;
        for (ExhibitorImport data : dataList) {
            List<String> errorMsg = CollectionUtil.newArrayList();
            // 验证展商名称不为空
            if (StrUtil.isBlank(data.getCompanyName())) {
                errorMsg.add("展商名称为空");
            }
            if (StrUtil.isBlank(data.getCompanyNameEn())) {
                errorMsg.add("展商英文名称为空");
            }
            // 验证展位号不为空
            if (StrUtil.isBlank(data.getStandNo())) {
                errorMsg.add("展位号为空");
            }
            if (errorMsg.size() > 0) {
                errors.add(count);
                errorList.add(new ExcelImportResult.Error(count, String.join(";", errorMsg)));
            } else {
                Exhibitor exhibitor = new Exhibitor();
                exhibitor.setCompanyName(data.getCompanyName());
                exhibitor.setCompanyNameEn(data.getCompanyNameEn());
                exhibitor.setStandNo(data.getStandNo());
                exhibitor.setCollectCount(0);
                String companyNamePy = StrUtil.trimToEmpty(JPinYinUtil.changeToTonePinYin(exhibitor.getCompanyName()));
                exhibitor.setCompanyNamePy(companyNamePy.substring(0,Math.min(150,companyNamePy.length())));

                String companyNameEnPy = StrUtil.trimToEmpty(JPinYinUtil.changeToTonePinYin(exhibitor.getCompanyNameEn()));
                exhibitor.setCompanyNameEnPy(companyNameEnPy.substring(0,Math.min(150,companyNameEnPy.length())));
                exhibitorService.save(exhibitor);
                Set<String> typeIds= new HashSet<>();
                List<ProductType> types = productTypeMapper.findByName(data.getProductTypeNames());
                if(CollUtil.isNotEmpty(types)){//通过子类  将其所有父级类别 归类
                    for (ProductType type: types
                         ) {
                        typeIds.add(type.getId());
                        String parentIds = type.getParentIds();
                        if(StrUtil.isNotBlank(parentIds)){
                            parentIds = parentIds.replaceAll("\\[","").replaceAll("]","");
                            String[] strs = parentIds.split(",");
                            if(ArrayUtil.isNotEmpty(strs) ){
                                for (String str:strs
                                     ) {
                                    if(StrUtil.isNotBlank(str)  && !"0".equals(str)){
                                        typeIds.add(str);
                                    }

                                }
                            }
                        }

                    }
                }

                if (CollUtil.isNotEmpty(typeIds)) {
                    List<ExhibitorProductType> exhibitorProductTypeList = new ArrayList<>();
                    for (String typeId : typeIds
                    ) {
                        ExhibitorProductType ept = new ExhibitorProductType();
                        ept.setExhibitorId(exhibitor.getId());
                        ept.setProductTypeId(typeId);
                        exhibitorProductTypeList.add(ept);
                    }
                    exhibitorProductTypeService.saveOrUpdateAll(exhibitorProductTypeList);
                }

            }
            count++;
        }

        ExcelImportResult result = new ExcelImportResult(dataList.size() - errors.size(), errorList);
        return new ResultUtil<Object>().setData(result);
    }
}
